import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

/**
 * Game Panel
 */
public class GamePanel extends JPanel implements KeyListener, ActionListener {
    //速度控制器，默认100，数值越小速度越快
    Timer timer = new Timer(100, this);
    //随机数构造
    Random random = new Random();
    //游戏开始状态，true代表已开始
    boolean isStart = false;
    //是否失败，true代表某玩家死亡
    boolean isFail = false;
    //是否胜利，true代表某玩家胜利
    boolean isPass = false;
    //胜利玩家 Player 1 / Player 2
    String winner = "";

    //绿苹果坐标
    int applex;
    int appley;

    //红苹果坐标
    int poisonx;
    int poisony;

    /**
     * 玩家1的信息
     */
    //生命
    int life1;
    //长度
    int length1;
    //坐标，100代表最大长度
    int[] player1X = new int[100];
    int[] player1Y = new int[100];
    //控制器，WASD
    String ctrl1;
    //积分
    int score1;

    /**
     * 玩家1的信息
     */
    //生命
    int life2;
    //长度
    int length2;
    //坐标，100代表最大长度
    int[] player2X = new int[100];
    int[] player2Y = new int[100];
    //控制器，WASD
    String ctrl2;
    //积分
    int score2;

    /**
     * 游戏开始
     */
    public GamePanel() {
        //初始化信息
        init();
        //设置键盘监听
        this.setFocusable(true);
        this.addKeyListener(this);
        timer.start();
    }

    /**
     * 初始化信息
     */
    public void init() {
        //默认4条生命
        life1 = 4;
        //默认长度为3，1个头2个身体
        length1 = 3;
        //初始坐标
        player1X[0] = 100;
        player1Y[0] = 100;
        player1X[1] = 90;
        player1Y[1] = 100;
        player1X[2] = 80;
        player1Y[2] = 100;
        //初始行进方向
        ctrl1 = "D";
        //初始分数
        score1 = 0;

        //默认4条生命
        life2 = 4;
        //默认长度为3，1个头2个身体
        length2 = 3;
        //初始坐标
        player2X[0] = 380;
        player2Y[0] = 100;
        player2X[1] = 390;
        player2Y[1] = 100;
        player2X[2] = 400;
        player2Y[2] = 100;
        //初始行进方向
        ctrl2 = "D";
        //初始分数
        score2 = 0;

        //随机刷新食物位置
        refreshFood();
    }

    /**
     * 随机刷新食物位置
     */
    public void refreshFood() {
        //绿苹果位置
        applex = 10 + 10 * random.nextInt(48);
        appley = 60 + 10 * random.nextInt(48);
        //红苹果位置
        poisonx = 10 + 10 * random.nextInt(48);
        poisony = 60 + 10 * random.nextInt(48);
    }


    /**
     * 游戏面板绘制
     *
     * @param g
     */
    @Override
    protected void paintComponent(Graphics g) {
        //清空面板
        super.paintComponent(g);
        //设置面板背景色
        this.setBackground(Color.BLACK);

        //绘制游戏主面板
        g.setColor(Color.WHITE);
        g.fillRect(0, 49, 500, 1);
        g.setColor(Color.BLACK);
        g.fillRect(0, 50, 500, 550);

        //绘制初始食物
        Data.apple.paintIcon(this, g, applex, appley);
        Data.poison.paintIcon(this, g, poisonx, poisony);

        //绘制玩家1
        Data.head1.paintIcon(this, g, player1X[0], player1Y[0]);
        for (int i = 1; i < length1; i++) {
            Data.body1.paintIcon(this, g, player1X[i], player1Y[i]);
        }

        //绘制玩家1的生命数量
        if (life1 > 0) {
            Data.player1.paintIcon(this, g, 20, 8);
        }
        if (life1 > 1) {
            Data.player1.paintIcon(this, g, 35, 8);
        }
        if (life1 > 2) {
            Data.player1.paintIcon(this, g, 50, 8);
        }
        if (life1 > 3) {
            Data.player1.paintIcon(this, g, 65, 8);
        }

        //绘制玩家1的积分
        g.setColor(Color.LIGHT_GRAY);
        g.setFont(new Font("", Font.BOLD, 14));
        g.drawString("Score ", 24, 40);
        g.setColor(Color.GREEN);
        g.setFont(new Font("", Font.BOLD, 16));
        g.drawString(score1 + "", 74, 40);

        //绘制玩家2
        Data.head2.paintIcon(this, g, player2X[0], player2Y[0]);
        for (int i = 1; i < length2; i++) {
            Data.body2.paintIcon(this, g, player2X[i], player2Y[i]);
        }

        //绘制玩家2的生命数量
        if (life2 > 0) {
            Data.player2.paintIcon(this, g, 440, 8);
        }
        if (life2 > 1) {
            Data.player2.paintIcon(this, g, 425, 8);
        }
        if (life2 > 2) {
            Data.player2.paintIcon(this, g, 410, 8);
        }
        if (life2 > 3) {
            Data.player2.paintIcon(this, g, 395, 8);
        }

        //绘制玩家2的积分
        g.setColor(Color.LIGHT_GRAY);
        g.setFont(new Font("", Font.BOLD, 14));
        g.drawString("Score ", 400, 40);

        g.setColor(Color.CYAN);
        g.setFont(new Font("", Font.BOLD, 16));
        g.drawString(score2 + "", 450, 40);

        //游戏未开始的初始状态
        if (!isStart) {
            //绘制游戏名称和开始提示
            g.setColor(Color.WHITE);
            g.setFont(new Font("", Font.BOLD, 30));
            g.drawString("Gluttonous Snake", 120, 250);
            g.setColor(Color.LIGHT_GRAY);
            g.setFont(new Font("", Font.BOLD, 22));
            g.drawString("Press Space", 180, 340);

            //绘制玩家1的操作按键提示
            g.setColor(Color.GREEN);
            g.drawString("Player 1", 25, 544);
            g.drawRect(50, 440, 30, 30);
            g.setFont(new Font("", Font.BOLD, 24));
            g.drawString("W", 54, 464);
            g.drawRect(10, 480, 30, 30);
            g.setFont(new Font("", Font.BOLD, 24));
            g.drawString("A", 17, 504);
            g.drawRect(50, 480, 30, 30);
            g.setFont(new Font("", Font.BOLD, 24));
            g.drawString("S", 57, 504);
            g.drawRect(90, 480, 30, 30);
            g.setFont(new Font("", Font.BOLD, 24));
            g.drawString("D", 97, 504);

            //绘制玩家2的操作按键提示
            g.setColor(Color.CYAN);
            g.drawString("Player 2", 380, 544);
            g.drawRect(410, 440, 30, 30);
            g.setFont(new Font("", Font.BOLD, 24));
            g.drawString("↑", 418, 464);
            g.drawRect(370, 480, 30, 30);
            g.setFont(new Font("", Font.BOLD, 24));
            g.drawString("←", 374, 504);
            g.drawRect(410, 480, 30, 30);
            g.setFont(new Font("", Font.BOLD, 24));
            g.drawString("↓", 418, 504);
            g.drawRect(450, 480, 30, 30);
            g.setFont(new Font("", Font.BOLD, 24));
            g.drawString("→", 454, 504);
        }

        //游戏失败或胜利
        if (isFail || isPass) {
            //绘制胜利后的提示文字
            g.setColor(Color.GREEN);
            g.setFont(new Font("", Font.BOLD, 30));
            g.drawString(winner + " Wins !", 145, 250);
            g.setColor(Color.LIGHT_GRAY);
            g.setFont(new Font("", Font.BOLD, 22));
            g.drawString("Press Space", 180, 340);
        }
    }

    /**
     * 键盘监听事件
     *
     * @param e
     */
    @Override
    public void keyPressed(KeyEvent e) {
        //获取键盘
        int keyCode = e.getKeyCode();

        //监听空格键，控制开始/暂停游戏
        if (keyCode == KeyEvent.VK_SPACE) {
            if (isFail) {
                isFail = false;
                init();
            } else if (isPass) {
                isPass = false;
                init();
            } else {
                isStart = !isStart;
            }
            repaint();
        }

        //监听玩家1的按键行为，WASD
        if (keyCode == KeyEvent.VK_A && !"R".equals(ctrl1)) {
            ctrl1 = "L";
        } else if (keyCode == KeyEvent.VK_W && !"D".equals(ctrl1)) {
            ctrl1 = "U";
        } else if (keyCode == KeyEvent.VK_S && !"U".equals(ctrl1)) {
            ctrl1 = "D";
        } else if (keyCode == KeyEvent.VK_D && !"L".equals(ctrl1)) {
            ctrl1 = "R";
        }

        //监听玩家2的按键行为，↑←↓→
        if (keyCode == KeyEvent.VK_LEFT && !"R".equals(ctrl2)) {
            ctrl2 = "L";
        } else if (keyCode == KeyEvent.VK_UP && !"D".equals(ctrl2)) {
            ctrl2 = "U";
        } else if (keyCode == KeyEvent.VK_DOWN && !"U".equals(ctrl2)) {
            ctrl2 = "D";
        } else if (keyCode == KeyEvent.VK_RIGHT && !"L".equals(ctrl2)) {
            ctrl2 = "R";
        }
    }

    /**
     * 定时器
     *
     * @param e
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        //当玩家1积分达到100，则游戏结束，玩家1胜利
        if (score1 >= 100) {
            isPass = true;
            winner = "Player 1";
            repaint();
        }
        //当玩家2积分达到100，则游戏结束，玩家2胜利
        if (score2 >= 100) {
            isPass = true;
            winner = "Player 2";
            repaint();
        }
        //如果游戏正在进行
        if (isStart && !isFail && !isPass) {
            //挪动玩家1的蛇身
            for (int i = length1 - 1; i > 0; i--) {
                player1X[i] = player1X[i - 1];
                player1Y[i] = player1Y[i - 1];
            }

            //玩家1的按键行为
            //触碰到边缘，如果生命仅余1条，则直接死亡，游戏结束，玩家2胜利，否则生命-1，自动转向继续游戏
            switch (ctrl1) {
                case "R":
                    player1X[0] = player1X[0] + 10;
                    if (player1X[0] > 470) {
                        if (life1 == 1) {
                            isFail = true;
                            winner = "Player 2";
                        } else {
                            life1--;
                            ctrl1 = player1Y[0] > 300 ? "U" : "D";
                        }
                    }
                    break;
                case "L":
                    player1X[0] = player1X[0] - 10;
                    if (player1X[0] < 10) {
                        if (life1 == 1) {
                            isFail = true;
                            winner = "Player 2";
                        } else {
                            life1--;
                            ctrl1 = player1Y[0] > 300 ? "U" : "D";
                        }
                    }
                    break;
                case "U":
                    player1Y[0] = player1Y[0] - 10;
                    if (player1Y[0] < 60) {
                        if (life1 == 1) {
                            isFail = true;
                            winner = "Player 2";
                        } else {
                            life1--;
                            ctrl1 = player1X[0] > 250 ? "L" : "R";
                        }
                    }
                    break;
                case "D":
                    player1Y[0] = player1Y[0] + 10;
                    if (player1Y[0] > 550) {
                        if (life1 == 1) {
                            isFail = true;
                            winner = "Player 2";
                        } else {
                            life1--;
                            ctrl1 = player1X[0] > 250 ? "L" : "R";
                        }
                    }
                    break;
            }

            //玩家1吃到绿苹果，身体长度+1，积分+10，刷新食物位置
            if (player1X[0] == applex && player1Y[0] == appley) {
                length1++;
                player1X[length1 - 1] = applex - 1;
                player1Y[length1 - 1] = appley - 1;
                score1 = score1 + 10;
                refreshFood();
            }

            //玩家1吃到红苹果，如果生命仅余1条，则直接死亡，游戏结束，玩家2胜利，否则生命-1，刷新食物，继续游戏
            if (player1X[0] == poisonx && player1Y[0] == poisony) {
                if (life1 == 1) {
                    isFail = true;
                    winner = "Player 2";
                } else {
                    life1--;
                    refreshFood();
                }
            }

            //玩家1咬到自己，如果生命仅余1条，则直接死亡，游戏结束，玩家2胜利，否则生命-1，继续游戏
            for (int i = 1; i < length1; i++) {
                if (player1X[0] == player1X[i] && player1Y[0] == player1Y[i]) {
                    if (life1 == 1) {
                        isFail = true;
                        winner = "Player 2";
                    } else {
                        life1--;
                    }
                    break;
                }
            }

            //挪动玩家2的蛇身
            for (int i = length2 - 1; i > 0; i--) {
                player2X[i] = player2X[i - 1];
                player2Y[i] = player2Y[i - 1];
            }

            //玩家2的按键行为
            //触碰到边缘，如果生命仅余1条，则直接死亡，游戏结束，玩家1胜利，否则生命-1，自动转向继续游戏
            switch (ctrl2) {
                case "R":
                    player2X[0] = player2X[0] + 10;
                    if (player2X[0] > 470) {
                        if (life2 == 1) {
                            isFail = true;
                            winner = "Player 1";
                        } else {
                            life2--;
                            ctrl2 = player2Y[0] > 300 ? "U" : "D";
                        }
                    }
                    break;
                case "L":
                    player2X[0] = player2X[0] - 10;
                    if (player2X[0] < 10) {
                        if (life2 == 1) {
                            isFail = true;
                            winner = "Player 1";
                        } else {
                            life2--;
                            ctrl2 = player2Y[0] > 300 ? "U" : "D";
                        }
                    }
                    break;
                case "U":
                    player2Y[0] = player2Y[0] - 10;
                    if (player2Y[0] < 60) {
                        if (life2 == 1) {
                            isFail = true;
                            winner = "Player 1";
                        } else {
                            life2--;
                            ctrl2 = player2X[0] > 250 ? "L" : "R";
                        }
                    }
                    break;
                case "D":
                    player2Y[0] = player2Y[0] + 10;
                    if (player2Y[0] > 550) {
                        if (life2 == 1) {
                            isFail = true;
                            winner = "Player 1";
                        } else {
                            life2--;
                            ctrl2 = player2X[0] > 250 ? "L" : "R";
                        }
                    }
                    break;
            }

            //玩家2吃到绿苹果，身体长度+1，积分+10，刷新食物位置
            if (player2X[0] == applex && player2Y[0] == appley) {
                length2++;
                player2X[length2 - 1] = applex - 1;
                player2Y[length2 - 1] = appley - 1;
                score2 = score2 + 10;
                refreshFood();
            }

            //玩家2吃到红苹果，如果生命仅余1条，则直接死亡，游戏结束，玩家1胜利，否则生命-1，刷新食物，继续游戏
            if (player2X[0] == poisonx && player2Y[0] == poisony) {
                if (life2 == 1) {
                    isFail = true;
                    winner = "Player 1";
                } else {
                    life2--;
                    refreshFood();
                }
            }

            //玩家2咬到自己，如果生命仅余1条，则直接死亡，游戏结束，玩家1胜利，否则生命-1，继续游戏
            for (int i = 1; i < length2; i++) {
                if (player2X[0] == player2X[i] && player2Y[0] == player2Y[i]) {
                    if (life2 == 1) {
                        isFail = true;
                        winner = "Player 1";
                    } else {
                        life2--;
                    }
                    break;
                }
            }
            repaint();
        }
        timer.start();
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }
}